screeclayproggramingfandomcom-20200214-history
Unity3D Building Damage Tutorial- Part IV - Simple Fire
Okay. I decided to make my mesh burn. As we all now, a mesh consists of verticles and triangles, and in my Meshmanager, from Aliases and Triangles. Our goal is to make a simple simulation of spreading fire. We will use Aliases as the basic "fireable things". To to this, we have to. #Produce a method to allow the programmer to arson an Alias. #Make something that will allow the fire to spread from one to other Aliases. #Add some kind of Update feature to Alias. This is needed to simulate fire spreading in some constant time. So, lets start a fire of Alias. In the place in Building.cs where Destroy(0.02f) we will put StartFire(100); That mean that Alias number 100 will start fire on click. StartFire method (MeshManager.cs) public void StartFire(int verticleNumber){ if((verticleNumber > Aliases.Count)&&verticleNumber>=0){return;} //1 if(meshState VerticleState.Standard){ //2 AliasesverticleNumber.StartFire(); //3 meshState = VerticleState.Burning; //4 } } #First we check if verticlenumber passed is valid. If no, we return, effectively terminating function. #We check the meshState. You see, i added new variable to MeshManager class. private VerticleState meshState; I than initialise it to be Standard. The name of enum is not entirely correct: VerticleState. But for now it will do. The aim of it, is to give information of mesh. Is it burning? Has it arleady burned? Anyway, here it check if it is standart. If so, we (3) pass the info to Alias of certain number, and set meshState to Burning(4). Becouse of that, that info will be passed only one time, even if we click more. StartFire method (Verticle.cs) public void StartFire(){ if(!TryingToBeFired){ TryingToBeFired = true; } } Well, i added a TryingToBeFired bool as a variable, inisialised with false. It may look awkward, but there is a reason for that. I will tell about it later. Alyway, there is no damage or anything intresting here. Why? Becouse all mesh-changing things will be started in Update method. Update (Verticle.cs) public void Update(){ if(state VerticleState.Destroyed){ //1 return; } if(health<=0){ //2 Destroy(); state = VerticleState.Destroyed; return; } if(state VerticleState.Burning){ //3 InflictDamage(); TryToFireLinkedAliases(); } if(TryingToBeFired&&state != VerticleState.Burning){//4 state = VerticleState.Burning; } } Well, the idea here is that this Update will be called every second, or so. 1) We simply check if Alias is estroyed. If so, there is no need for making anything 2) I added a variable, health. It is a flaot, it starts as 1.0, and means the current "health" of verticle. We will decrease this health in InflictDamage method. Than, if it is < 0, here the verticle will be destroyed. By Simply changing state and calling Destroy method 3) This starts when the Alias is burning. If it is, we InflictDamage and TryToFireLinkedAliases. 4) When some other Alias has "passed" its fire to us, we change the state to burning. Why here? To answer it, we have to look at TellAliasesToUpdate function in MeshManager class TellAliasesToUpdate (MeshManager.cs) public void TellAliasesToUpdate(){ for(int k=0; kTryToFireLinkedAliases function is called, which sets any linked alias, like number 11's, state to Burning. In that way, when Update will be called on number 11, the InflictDamage and TryToFireLinkedAliases method will be called. And again, lets say that it has a Alias nr 12 as LinkedAlias. etc. etc. In this way, in THE SAME TellAliasesToUpdate loop, many Aliases will start to be burning. When i added TryingToBeFired bool, and changing state relative to it, InflictDamage and TryToFireLinkedAliases will be started at NEXT update. In that way, fire will be spreading naturally, and not in instant way. InflictDamage method (Verticle.cs) public void InflictDamage(){ health -= 0.1f; } Simply subtracting 0.1f from health. Very simple, but will do now. Later, we can add some radomness here. TryToFireLinkedAliases (Verticle.cs) public void TryToFireLinkedAliases(){ foreach(int k in LinkedAliases){ OwnerManager.Aliasesk.StartFire(); } } Easy. Stating TellAliasesToUpdate One last thing. We have to tell these MeshManagers to start this function every frame, or every second, or every other thing. You see, i cannot simple use overriden Update method as Verticle nor MeshManager class inherits from MonoBehaviour. Had i added it, i couldn't use "new Verticle(...)" or new MeshManager, only add it as component. In Building.cs we have true Update. Lets call TellAliasesToUpdate there protected override void Update () { base.Update(); ProcessBuildQueue(); for(int i=0; i Then we have to edit TellAliasesToUpdate, or else it will be called every frame, thus damage will be too fase. TellAliasesToUpdate method (MeshManager.cs) First I'll add a new variable after other variables on top of page private float time = 0f; then, our method public void TellAliasesToUpdate(){ if(time>1){ for(int k=0; k